import React, {useEffect, useCallback, useState} from "react";

/**
 * useCallback：
 *     1. 返回一个 memoized 回调函数。
 *     2. 把内联回调函数及依赖项数组作为参数传入 useCallback，
 *     它将返回该回调函数的 memoized 版本，该回调函数仅在某个依赖项改变时才会更新。
 *     3. 当你把回调函数传递给经过优化的并使用引用相等性去避免非必要渲染（例如 shouldComponentUpdate）的子组件时，
 *     它将非常有用。
 *     4. useCallback(fn, deps) 相当于 useMemo(() => fn, deps)。
 *     5. 依赖项数组不会作为参数传给回调函数。
 *     6. 我们使函数本身只在需要的时候才改变，而不是去掉对函数的依赖。
 *
 * 分析：
 *     1. 我们要感谢useCallback，因为如果 query 保持不变，getFetchUrl也会保持不变，我们的effect也不会重新运行。
 *     2. 如果query修改了，getFetchUrl也会随之改变，因此会重新请求数据。
 *
 * 注意：
 *     1. 如果一个函数没有使用组件内的任何值，你应该把它提到组件外面去定义，
 *     然后就可以自由地在effects中使用
 *
 */
export function HookTest5() {
    // eslint-disable-next-line no-unused-vars
    const [query, setQuery] = useState('react');

    const getFetchUrl = useCallback((query) => {
        return 'https://hn.algolia.com/api/v1/search?query=' + query;
    }, [query]);

    useEffect(() => {
        // eslint-disable-next-line no-unused-vars
        const url = getFetchUrl();
    }, [getFetchUrl]);

    useEffect(() => {
        // eslint-disable-next-line no-unused-vars
        const url = getFetchUrl();
    }, [getFetchUrl]);

    return (
        <div>...</div>
    );
}

// 如果一个函数没有使用组件内的任何值，你应该把它提到组件外面去定义，然后就可以自由地在effects中使用
function getFetchUrl(query) {
    return 'https://hn.algolia.com/api/v1/search?query=' + query;
}

// eslint-disable-next-line no-unused-vars
function SearchResults() {
    useEffect(() => {
        // eslint-disable-next-line no-unused-vars
        const url = getFetchUrl('react');
    }, []);

    useEffect(() => {
        // eslint-disable-next-line no-unused-vars
        const url = getFetchUrl('redux');
    }, []);
}

// 还可以使用 useCallback
// eslint-disable-next-line no-unused-vars
function SearchResults2() {
    const getFetchUrl = useCallback((query) => {
        return 'https://hn.algolia.com/api/v1/search?query=' + query;
    }, []);

    useEffect(() => {
        // eslint-disable-next-line no-unused-vars
        const url = getFetchUrl('react');
    }, [getFetchUrl]);

    useEffect(() => {
        // eslint-disable-next-line no-unused-vars
        const url = getFetchUrl('redux');
    }, [getFetchUrl]);
}
